package server;

import java.io.IOException;
import java.rmi.ConnectException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Properties;
import java.util.Scanner;

import rmiClient.ManagementClientCallback;
import service.Event;
import service.SubscriptionHolder;
import service.StatisticsHolder;


public class AnalyticsServer extends java.rmi.server.UnicastRemoteObject implements ProcessEventInterface, SubscriptionInterface {

	private Registry registry;
	private int port;
	private String host;
	private SubscriptionHolder subHolder = SubscriptionHolder.getInstance();
	private String analyticsName;
	private StatisticsHolder statHolder;



	public static void main(String[] args) {

		try {
			AnalyticsServer server = new AnalyticsServer(args);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
	}
	
	
	private void run() throws RemoteException {
		Scanner stdin =  new Scanner(System.in);
		String userinput;
		boolean isActive = true;
		while (isActive) {
			userinput=stdin.nextLine().trim();
			if(userinput.equals("!exit")) {
				shutDown();
				isActive = false;
			}

		}
		stdin.close();
	}

	private AnalyticsServer(String[] args) throws RemoteException {
		statHolder = StatisticsHolder.getInstance(this);
		
		try {
			Properties props = new Properties();
			java.io.InputStream is = ClassLoader.getSystemResourceAsStream("./registry.properties");
			props.load(is);

			if (is != null) {
				try {			
					

					port = Integer.parseInt(props.getProperty("registry.port"));
					host = props.getProperty("registry.host");
					
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} finally {
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			} else {
				System.err.println("Properties file not found!");
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		if(args.length!=1) usage();
		analyticsName=args[0];
		
		try {
			registry = LocateRegistry.getRegistry(host,port);
			registry.rebind(analyticsName, this);
		} catch (ConnectException e) {
			registry = LocateRegistry.createRegistry(port);
			registry.rebind(analyticsName, this);
		}
		
		run();
	}



	private void usage() {
		System.out.println("Usage: java AnalyticsServer <analytics server binding name>\nExample: java AnalyticsServer analyticsServer");
		System.exit(0);
	}

	/**
	 * rmi, invoked by management-client
	 * receives callback object from clients to send notifications
	 * @param filter
	 * @return unique identifier String
	 */
	@Override
	public String subscribe(String filter, ManagementClientCallback client) throws RemoteException {
		return subHolder.addSubscription(filter, client);
	}

	//rmi, invoked by management-client
	@Override
	public int unsubscribe(String id) throws RemoteException {
		return subHolder.deleteSubscription(id);
	}


	//rmi, invoked by bidding-server
	@Override
	public void processEvent(Event e) throws RemoteException {
		notify(e);
		statHolder.createStatisticsEvent(e);
	}

	public void notify(Event e) throws RemoteException {
		subHolder.notify(e);
	}
	
	private void shutDown() throws RemoteException {
		try {
			registry.unbind(analyticsName);
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		UnicastRemoteObject.unexportObject(this, true);
		System.exit(0);
	}





}

